#include "Client.h"
#include <iostream>
#include <windows.h>

Client::Client(IBuffer *buffer, unsigned int bufferReadSize) :
_buffer(buffer),
_bufferReadSize(bufferReadSize)
{

}

Client::~Client()
{
	delete _connection;
}

int Client::Connect(std::string adress, int port)
{
    int result = 0;

 _connection = new Connection(port, 0, adress, 0);
 result = _connection->Start();
 result = _connection->CreateSocket();
 result = _connection->CreateConnection();
 if (result >= 0)
 {
 DWORD dwThreadId;
 CreateThread
 (
	NULL,
	0,
	reinterpret_cast<LPTHREAD_START_ROUTINE>(Client::runSelectReceive),
	this,
	0,
	&dwThreadId
 );
 }
 return (result);
}

void Client::runSelectReceive(void* data)
{
	Client *client = reinterpret_cast<Client*>(data);
    fd_set fd;
    int check;
	int len;
	char *buff = new char[client->_bufferReadSize];

	while(1)
	{
		FD_ZERO(&fd);
		FD_SET(client->_connection->getSock(), &fd);
		check = select(1, &fd, NULL, NULL, 0);
		if (check > 0 && FD_ISSET(client->_connection->getSock(), &fd))
		{
			len = recv(client->_connection->getSock(), buff, 1024, 0);
			if (len > 0)
			{
				client->_buffer->Write(buff, len);
			}
			else
			{
				std::cout << "error receive" << std::endl;
				client->Disconnect();
				break;
			}
		}
		else
		{
			std::cout << "error select" << std::endl;
			client->Disconnect();
			break;
		}
	}
	delete buff;
}

int Client::Disconnect()
{
	return (_connection->CloseSocket());   
}

int Client::Send(void *buff, unsigned int len)
{
	static int i = 0;
	fd_set fd;
	struct timeval timer;

	FD_ZERO(&fd);
	FD_SET(this->_connection->getSock(), &fd);
	timer.tv_sec = 5;
	timer.tv_usec = 0;

	int check = select(1, NULL, &fd,  NULL, &timer);
	if (check > 0 && FD_ISSET(this->_connection->getSock(), &fd))
	{
		//std::cout << i++ << std::endl;
		if (send(_connection->getSock(), static_cast<const char*>(buff), len, 0) < 0)
		{
			std::cerr << "Error : client send\n" << std::endl;
			return (-1);
		}
		return (0);
	}
	return -1;
}